package cn.rokhdelar.ams.common.service.impl;

import cn.rokhdelar.ams.common.config.OssConfig;
import cn.rokhdelar.ams.common.domain.dto.OssPolicyResult;
import cn.rokhdelar.ams.common.domain.po.OssFile;
import cn.rokhdelar.ams.common.mapper.OssFileMapper;
import cn.rokhdelar.ams.common.service.OssService;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.UUID;

@Service
public class OssServiceImpl implements OssService {

    private final OssConfig ossConfig;
    private final OssFileMapper ossFileMapper;

    public OssServiceImpl(OssConfig ossConfig, OssFileMapper ossFileMapper) {
        this.ossConfig = ossConfig;
        this.ossFileMapper = ossFileMapper;
    }

    @Override
    public OssPolicyResult policy() {
        OssPolicyResult result = new OssPolicyResult();

        // 设置参数
        result.setAccessKeyId(ossConfig.getAccessKey());
        result.setPolicy(generatePolicy());
        result.setSignature(generateSignature(result.getPolicy()));
        result.setDir(UUID.randomUUID().toString()); // 随机目录名
        result.setHost("https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint());
        result.setExpire(String.valueOf(System.currentTimeMillis() + ossConfig.getExpireTime() * 1000));

        return result;
    }

    @Override
    public void saveFileRecord(OssFile ossFile) {
        ossFile.setCreateTime(LocalDateTime.now());
        ossFileMapper.insert(ossFile);
    }

    @Override
    public boolean deleteFileRecord(Long id) {
        return ossFileMapper.deleteById(id) > 0;
    }

    private String generatePolicy() {
        JSONObject policy = new JSONObject();
        policy.put("expiration", System.currentTimeMillis() + ossConfig.getExpireTime() * 1000);
        JSONObject conditions = new JSONObject();
        conditions.put("bucket", ossConfig.getBucketName());
        conditions.put("content-length-range", ossConfig.getMaxSize());
        policy.put("conditions", conditions);
        return Base64.encodeBase64String(policy.toJSONString().getBytes(StandardCharsets.UTF_8));
    }

    private String generateSignature(String policy) {
        try {
            Mac hmac = Mac.getInstance("HmacSHA1");
            hmac.init(new SecretKeySpec(ossConfig.getSecretKey().getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
            byte[] signData = hmac.doFinal(policy.getBytes(StandardCharsets.UTF_8));
            return Base64.encodeBase64String(signData);
        } catch (Exception e) {
            throw new RuntimeException("生成OSS签名失败", e);
        }
    }
}